package team

import (
	"autoDeploy/config"
	"autoDeploy/dao/myselfMysql"
	"autoDeploy/models"
	"autoDeploy/utils/DingTalk"
	"autoDeploy/utils/Port"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"log"
)

var db, _ = myselfMysql.CreateMySQLClient(config.MysqlDb)

//	UserAddTeamToDB
//
// 描述信息： 将团队信息添加至数据库
//
// Param：
//
//	teamName ：团队名称
//	captainUserId ：队长id
//	address ：团队通讯地址
//
// Return：
//
//	int：1 正常； 0 已存在； -1 插入错误；-2 为队长分配权限错误
//	err ：错误信息
func UserAddTeamToDB(teamName string, captainUserId uint64, address string) (int, error) {
	// 检查是否已经存在具有相同队长和团队名称的记录
	var existingTeam models.Team
	if result := db.Where("name = ? AND captain_user_id = ?", teamName, captainUserId).First(&existingTeam); result.Error == nil {
		// 如果存在，返回 code 0 和错误信息
		return 0, fmt.Errorf("team with the same name and captain already exists")
	}

	// 创建一个团队
	team := models.Team{
		Name:          teamName,
		CaptainUserID: captainUserId,
		Status:        true, // 默认状态为 1 (true)
		Address:       address,
	}

	// 插入数据
	if err := db.Create(&team).Error; err != nil {
		// 如果插入失败，返回 code -1 和错误信息
		return -1, fmt.Errorf("failed to insert team data: %w", err)
	}

	// 插入成功，获取 team 的 ID
	teamID := team.ID

	// 将 captainUserId 和 teamID 插入到 user_teams 表
	userTeam := models.UserTeam{
		UserID: captainUserId,
		TeamID: teamID,
	}
	if err := db.Create(&userTeam).Error; err != nil {
		// 如果插入失败，返回 code -1 和错误信息
		return -1, fmt.Errorf("failed to insert user_team data: %w", err)
	}

	//为当前队长分配队长权限
	err := models.UserProRole{}.InsertIfNotExists(db, captainUserId, teamID, config.TeamCaptain)
	if err != nil {
		return -2, err
	}

	// 插入成功，返回 code 1 和成功信息
	fmt.Printf("Team created successfully: %+v\n", team)
	fmt.Printf("UserTeam created successfully: %+v\n", userTeam)
	return 1, nil
}

//	SendInvitation
//
// 描述信息：发送邀请信息
//
// Param：
//
//		teamName ：团队名
//		captainUserId ：队长id
//		phone ：被邀请人手机号
//	 webHookURL：团队通讯地址
//
// Return：
//
//	int ：状态码 0 1
//	error ：错误信息
func SendInvitation(teamName string, captainUserId uint64, phone string, webHookURL string, teamID uint64) (int, error) {
	//首先查询队长的信息
	captain, err := models.GetUserByID(db, captainUserId)
	if err != nil {
		return 0, err
	}

	//查询被邀请对象的信息
	member, err := models.GetUserByPhone(db, phone)
	if err != nil {
		return 0, err
	}

	err = DingTalk.SendMessageToDingTalk(webHookURL, member.Phone, captain.Username, teamName)
	if err != nil {
		return 0, err
	}

	//将消息插入到 notifications表中
	err = models.InsertInvitationNotification(db, captain.ID, captain.Username, member.ID, member.Username, teamID, teamName)
	if err != nil {
		return 0, err
	}

	return 1, nil

}

//	GetTeamInfo
//
// 描述信息： 根据团队id 返回成员数、成员、项目
//
// Param：
//
//	teamID ：团队id
//
// Return：
//
//	int ：成员数
//	[]models.User ：成员切片
//	models.Project ：项目
//	error ：错误信息
func GetTeamInfo(teamID uint64) (int, []models.User, models.Project, error) {
	// 1. 获取团队成员的个数和成员ID切片
	memberCount, userIDs, err := models.GetTeamMemberIDs(db, teamID)
	if err != nil {
		return 0, nil, models.Project{}, err // 发生错误，返回错误
	}

	// 2. 获取团队成员的详细信息
	var teamMembers []models.User
	if len(userIDs) > 0 {
		teamMembers, err = models.GetUserDetailsByID(db, userIDs)
		if err != nil {
			return 0, nil, models.Project{}, err // 发生错误，返回错误
		}
	}

	// 3. 获取团队的项目信息
	var teamProject models.Project
	teamProjectID, err := models.GetProjectIDByTeamID(db, teamID)
	if err != nil {
		return 0, nil, models.Project{}, err // 发生错误，返回错误
	}
	if teamProjectID != 0 {
		teamProject, err = models.GetProjectByID(db, teamProjectID)
		if err != nil {
			return 0, nil, models.Project{}, err // 发生错误，返回错误
		}
	}

	return memberCount, teamMembers, teamProject, nil
}

//	AddProjectToTeam
//
// 描述信息： 根据团队id，项目名称，项目git地址
//
// Param：
//
//	teamID ：团队id
//	gitAddress ：项目git地址
//	projectName ：项目名称
//
// Return：
//
//	int ：状态码 -1：表示项目创建失败，0：表示团队项目记录创建失败，1：表示成功，2：表示重复创建
//	error ：错误信息
func AddProjectToTeam(teamID uint64, projectAddress string, projectName string) (int, error) {

	var exist models.Project
	result := db.Where("git_address = ?", projectAddress).First(&exist)
	if result.Error == nil {
		// 查询成功，并且找到记录
		return 2, fmt.Errorf("project already exist")
	}

	//创建一条新的项目记录，并返回id
	project := models.Project{
		Name:       projectName,
		GitAddress: projectAddress,
		Port:       Port.GetPort(),
	}
	result = db.Create(&project)
	if result.Error != nil {
		log.Fatalf("failed to insert project: %v", result.Error)
		return -1, result.Error
	}
	//将项目id和团队id，插入到团队项目表中
	projectID := project.ID
	teamProject := models.TeamProject{
		TeamID:    teamID,
		ProjectID: projectID,
	}
	result = db.Create(&teamProject)
	if result.Error != nil {
		log.Fatalf("failed to insert team project: %v", result.Error)
		return 0, result.Error
	}

	return 1, nil
}

//	GetTeamDetailsByUserID
//
// 描述信息： 根据用户ID获取用户所属的所有团队及其成员的详细信息
//
// Param：
//
//	db ：数据库连接实例
//	userID ：用户id
//
// Return：
//
//	[]TeamDetail ：若干个 {Team {Members {User {Permission}}}}
//	error ：错误信息
func GetTeamDetailsByUserID(db *gorm.DB, userID uint64) ([]models.TeamDetail, error) {
	var teamDetails []models.TeamDetail

	// 获取用户所属的所有团队及其角色
	userTeamsAndRoles, err := models.GetUserTeamsAndRoles(db, userID)
	if err != nil {
		return nil, fmt.Errorf("failed to get user teams and roles: %w", err)
	}

	// 遍历每个团队
	for _, userTeamAndRole := range userTeamsAndRoles {
		var teamDetail models.TeamDetail

		// 获取团队信息
		team, err := models.Team{}.GetTeamByID(db, userTeamAndRole.TeamID)
		if err != nil {
			return nil, fmt.Errorf("failed to get team info: %w", err)
		}
		teamDetail.Team = team

		// 获取团队成员信息
		var members []models.UserAndProPermissionsDetail
		var userProRoles []models.UserProRole
		if err := db.Model(&models.UserProRole{}).Where("team_id = ?", userTeamAndRole.TeamID).Find(&userProRoles).Error; err != nil {
			return nil, fmt.Errorf("failed to get user pro roles: %w", err)
		}

		for _, userProRole := range userProRoles {
			var user models.User
			if err := db.Model(&models.User{}).Where("id = ?", userProRole.UserID).First(&user).Error; err != nil {
				return nil, fmt.Errorf("failed to get user info: %w", err)
			}

			// 获取用户权限
			permissionIDs, err := models.GetPermissionIDByProRoleID(db, userProRole.ProRoleID)
			if err != nil {
				return nil, fmt.Errorf("failed to get permissions by pro role id: %w", err)
			}

			permissions, err := models.GetPermissionsDetailsByIDSlice(db, permissionIDs)
			if err != nil {
				return nil, fmt.Errorf("failed to get permissions details: %w", err)
			}

			members = append(members, models.UserAndProPermissionsDetail{
				User:           user,
				ProPermissions: permissions,
			})
		}

		teamDetail.Members = members
		teamDetails = append(teamDetails, teamDetail)
	}

	return teamDetails, nil
}

//	GetUserResource
//
// 描述信息： 获取用户的团队以及团队成员角色详细信息
//
// Param：
//
//	userID ：用户id
//
// Return：
//
//	int ：0：根据id查询当前user对象失败；-1：根据用户id查询团队的详细信息失败；1：成功
//	models.User ：当前用户详细信息
//	[]models.TeamDetail ：用户团队详细信息列表
//	error ：错误信息
func GetUserResource(userID uint64) (int, models.User, []models.TeamDetail, error) {
	//1、根据id查询当前user对象
	user, err := models.GetUserByID(db, userID)
	if err != nil {
		return 0, models.User{}, []models.TeamDetail{}, err
	}

	//2、根据用户id查询团队的详细信息
	teamDetails, err := GetTeamDetailsByUserID(db, userID)
	if err != nil {
		return -1, models.User{}, []models.TeamDetail{}, err
	}

	return 1, user, teamDetails, nil

}

//	AgreeJoinTeam
//
// 描述信息： 将邮件接收者加入团队
//
// Param：
//
//	receiverId ：接收者id
//	teamId ：团队id
//
// Return：
//
//	int ：状态码：0加入失败，1加入成功
//	error ：错误信息
func AgreeJoinTeam(receiverId, teamId uint64) (int, error) {

	//往UserProRole表中插入数据
	err := models.UserProRole{}.InsertIfNotExists(db, receiverId, teamId, config.TeamMember)
	if err != nil {
		return 0, err
	}
	//往UserTeam表中插入数据
	err = models.UserTeam{}.InsertUserTeamIfNotExists(db, receiverId, teamId)
	if err != nil {
		return 0, err
	}

	return 1, nil
}

//	DropMember
//
// 描述信息： 踢出用户
//
// Param：
//
//	userID ：用户id
//	teamID ：团队id
//
// Return：
//
//	error ：错误信息
func DropMember(userID, teamID uint64) error {
	// 事务原子操作
	return db.Transaction(func(tx *gorm.DB) error {
		err := models.UserProRole{}.DeleteUserProRoleByUserIDAndTeamID(tx, userID, teamID)
		if err != nil {
			return errors.New("删除 user_pro_role 失败: " + err.Error())
		}

		// 第二步：删除 user_teams 这样写没有错误
		err = models.UserTeam{}.DeleteUserTeamByUserIDAndTeamID(tx, userID, teamID)
		if err != nil {
			return errors.New("删除 user_teams 失败: " + err.Error())
		}
		return nil
	})
}

//	GetTeamSum
//
// 描述信息： 根据用户id获取团队的数量
//
// Param：
//
//	userID ：用户id
//
// Return：
//
//	uint64 ：用户参加的团队数量
//	error ：错误信息
func GetTeamSum(userID uint64) (uint64, error) {
	teams, err := models.GetUserTeamIDs(db, userID)
	if err != nil {
		return 0, fmt.Errorf("service层获取团队id列表失败: %v", err.Error())
	}
	length := len(teams)
	return uint64(length), nil
}
